package io.renren.modules.mark.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import io.renren.common.exception.RRException;
import io.renren.common.utils.Constant;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.R;
import io.renren.modules.mark.constant.ItemConstant;
import io.renren.modules.mark.dao.MarkDatasetDao;
import io.renren.modules.mark.dao.MarkItemDao;
import io.renren.modules.mark.dao.MarkTeamUserDao;
import io.renren.modules.mark.entity.MarkDatasetEntity;
import io.renren.modules.mark.entity.MarkItemEntity;
import io.renren.modules.mark.entity.MarkTeamUserEntity;
import io.renren.modules.mark.form.ItemForm;
import io.renren.modules.mark.form.ItemPageForm;
import io.renren.modules.mark.form.Location;
import io.renren.modules.mark.form.MarkForm;
import io.renren.modules.mark.service.MarkItemService;
import io.renren.modules.mark.service.MarkTeamUserService;
import io.renren.modules.mark.utils.IdWorker;
import io.renren.modules.sys.controller.AbstractController;
import io.renren.modules.sys.dao.SysUserRoleDao;
import io.renren.modules.sys.entity.SysUserEntity;
import io.renren.modules.sys.entity.SysUserRoleEntity;
import io.renren.modules.sys.service.SysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 *
 *
 * @author
 * @email
 * @date
 */
@RestController
@RequestMapping("mark/markitem")
@Api(value = "markApi", description = "图片增删改查",  tags = {"图片接口"})
public class MarkItemController extends AbstractController{
    @Autowired
    private MarkItemService markItemService;

    @Autowired
    private MarkItemDao markItemDao;

    @Autowired
    private MarkDatasetDao markDatasetDao;

    @Autowired
    private MarkTeamUserDao markTeamUserDao;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private SysUserRoleDao sysUserRoleDao;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private MarkTeamUserService markTeamUserService;

    /**
     * 标记人员排行榜
     * @param startTime 开始时间
     * @param endTime 截止时间
     * @return 排行榜TOP 10
     */
    @GetMapping("/ranking")
    @ApiOperation("标记人员排行榜")
    public R ranking(String startTime,String endTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if(StringUtils.isBlank(endTime) || StringUtils.isBlank(startTime)){
           throw new RRException("开始时间和结束时间不能为空");
        }
        try {
            if(sdf.parse(startTime).compareTo(sdf.parse(endTime)) > 0){
                throw new RRException("开始日期不能大于截止日期");
            }
        } catch (ParseException e) {
            throw  new RRException("开始或截止日期格式解析错误,正确格式：yyyy-MM-dd HH:mm:ss ");
        }

        List<Map<String, String>> maps = markItemService.selectRanking(startTime, endTime);
        return R.ok().put("list",maps);
    }

    /**
     * 批量提交图片
     */
    @PostMapping("/updateItemState")
    @ApiOperation("批量提交图片")
    @RequiresPermissions("mark:markitem:mark")
    public R updateState(@RequestBody Long datasetId){
        Long userId = getUserId();
        UpdateWrapper<MarkItemEntity> uw = new UpdateWrapper<>();
        if(datasetId==-1){
            uw.set("state",ItemConstant.ItemType.MARK.getValue())
                    .set("update_time",new Date())
                    .eq("user_id",userId)
                    .eq("is_save",1)
                    .eq("state",ItemConstant.ItemType.SEND.getValue());
        }else{
            uw.set("state",ItemConstant.ItemType.MARK.getValue())
                    .set("update_time",new Date())
                    .eq("user_id",userId).eq("dataset_id",datasetId)
                    .eq("is_save",1)
                    .eq("state",ItemConstant.ItemType.SEND.getValue());
        }
        markItemService.update(uw);
        return R.ok();
    }


    /**
     * 用户根据itemId和datasetId查询图片信息，并返回当前图片任务的前一张和后一张图片ID
     */
    @GetMapping("/queryByItemId")
    @ApiOperation("根据图片Id获取图片信息")
    public R queryByItemId(Long itemId, Long datasetId,Integer state) {
        Long userId = getUserId();
        QueryWrapper<MarkItemEntity> qw = new QueryWrapper<>();
        qw.eq("item_id", itemId);
        Map map = new HashMap();
        map.put("itemId",itemId);
        if(datasetId!=null && datasetId != -1){
            map.put("datasetId",datasetId);
        }
        if (userId != 1) {
            map.put("userId",userId);
        }
        if(state==null || state==-1){
            map.put("stateEq",1);
        }else{
            map.put("state",state);
        }
        List<String> id = markItemDao.getPreAndNext(map);
        MarkItemEntity rel = markItemService.getOne(qw);
        if (rel == null) throw new RRException("未查询到图片请检查ID值是否对应");

        R ok = R.ok();
        ok.put("itemInfo", rel);
        ok.put("nextId", id.get(0));
        ok.put("preId", id.get(1));
        return ok;
    }

    @GetMapping("/queryApproveByItemId")
    @ApiOperation("根据图片Id获取图片信息")
    public R queryApproveByItemId(Long itemId, Long datasetId,Integer state) {
        QueryWrapper<MarkItemEntity> qw = new QueryWrapper<>();
        qw.eq("item_id", itemId);
        Map map = new HashMap();
        map.put("itemId",itemId);
        if(state==null || state==-1){
            map.put("stateEq",2);
        }else{
            map.put("state",state);
        }
        if(datasetId != -1){
            map.put("datasetId",datasetId);
        }else if(getUserId()!=1){
            Long userId = getUserId();
            Map<String, Object> map1 = new HashMap<>();
            map1.put("user_id",userId);
            List<MarkTeamUserEntity> teamList = markTeamUserDao.selectByMap(map1);
            List<Integer> teams = teamList.stream().map(team -> team.getTeamId()).collect(Collectors.toList());
            map.put("teams",teams);
        }
        List<String> id = markItemDao.getPreAndNext(map);
        MarkItemEntity rel = markItemService.getOne(qw);
        if (rel == null) throw new RRException("未查询到图片请检查ID值是否对应");

        R ok = R.ok();
        ok.put("itemInfo", rel);
        ok.put("nextId", id.get(0));
        ok.put("preId", id.get(1));
        return ok;
    }

    /**
     * 标注图片
     */
    @PostMapping("/updateLocation")
    @ApiOperation("标注图片")
    public R updateLocation(@Valid @RequestBody MarkForm markForm){
        Long itemId = markForm.getId();
        List<Location> locations = markForm.getLocations();
        Long userId = getUserId();
        QueryWrapper<MarkItemEntity> qw = new QueryWrapper<>();
        qw.eq("user_id",userId).eq("item_id",markForm.getId());
        MarkItemEntity entity = markItemService.getBaseMapper().selectById(itemId);
        if(entity.getUserId()!=userId){
            throw new RRException("该图片没有分给此用户，不能进行批注");
        }
        if(entity.getState()>=ItemConstant.ItemType.MARK.getValue()){
            throw new RRException("该图片已经提交审核，不能进行修改操作");
        }
        String jsoStr = JSON.toJSONString(locations);
        UpdateWrapper<MarkItemEntity> uw = new UpdateWrapper<>();
//        if(entity.getState()==ItemConstant.ItemType.EDIT.getValue()){
//            uw.set("location",jsoStr).set("is_save",1).set("state",ItemConstant.ItemType.SEND.getValue())
//                    .eq("item_id",itemId);
//        }
        uw.set("location",jsoStr).set("is_save",1).eq("item_id",itemId);
        markItemService.update(uw);
        return R.ok();
    }


    /**
     * 提交图片
     */
    @PostMapping("/submitItem")
    @ApiOperation("更新单张图片状态为已标记")
    public R submitItem(@Valid @RequestBody MarkForm markForm){
        Long userId = getUserId();
        MarkItemEntity entity = markItemService.getBaseMapper().selectById(markForm.getId());
        if(entity.getState()==ItemConstant.ItemType.MARK.getValue()){
            throw new RRException("该图片已经提交审核，不能重复提交");
        }
        if(entity.getState()==ItemConstant.ItemType.PASS.getValue()){
            throw new RRException("该图片已经审核完成，不能重复提交");
        }
        if(entity.getUserId()!=userId){
            throw new RRException("该图片没有分给此用户，不能进行提交");
        }
        List<Location> locations = markForm.getLocations();
        String jsoStr = JSON.toJSONString(locations);
        UpdateWrapper<MarkItemEntity> uw = new UpdateWrapper<>();
        uw.set("location",jsoStr).set("state",ItemConstant.ItemType.MARK.getValue()).set("is_save",1)
                .set("update_time",new Date())
                .eq("item_id",markForm.getId());
        markItemService.update(uw);
        return R.ok();
    }

    /**
     * 列表
     * 可选where条件：datasetId state userId
     */
    @GetMapping("/list")
    @ApiOperation("分页查询图片列表（字段都是非必须）")
    //@RequiresPermissions("mark:markitem:list")
    public R list(ItemPageForm itemPageForm){
        Map map = JSON.parseObject(JSON.toJSONString(itemPageForm), Map.class);
        PageUtils page = markItemService.queryPage(map);
        MarkDatasetEntity markDatasetEntity = null;
        if(itemPageForm.getDatasetId()!=null){
            markDatasetEntity = markDatasetDao.selectById(itemPageForm.getDatasetId());
        }
        R ok = R.ok();
        if(markDatasetEntity!=null){
            ok.put("name",markDatasetEntity.getName());
            ok.put("datasetId",markDatasetEntity.getDatasetId());
            ok.put("state",markDatasetEntity.getState());
        }
        ok.put("page", page);
        return ok;
    }

    /**
     * 列表
     * 查询需要批注的图片
     */
    @GetMapping("/listMark")
    @ApiOperation("需要批注的图片")
    public R listMark(ItemPageForm itemPageForm){
        Map map = JSON.parseObject(JSON.toJSONString(itemPageForm), Map.class);
        Long userId = getUserId();
        SysUserEntity user = getUser();
        if(userId!= Constant.SUPER_ADMIN && userId!= Constant.ADMIN){
            map.put("userId",userId);
        }
        if(itemPageForm.getDatasetId()!=null && itemPageForm.getDatasetId()==-1){
            map.remove("datasetId");
        }
        if(itemPageForm.getState()==null || itemPageForm.getState()==-1){
            map.put("min",ItemConstant.ItemType.SEND.getValue());
        }
        PageUtils page = markItemService.queryPage(map);
        R ok = R.ok();
        ok.put("page", page);
        return ok;
    }


    /**
     *
     * 查询需要审批的图片
     */
    @GetMapping("/listApprove")
    @ApiOperation("查询需要审批的图片")
    public R listApprove(ItemPageForm itemPageForm){
        Map map = JSON.parseObject(JSON.toJSONString(itemPageForm), Map.class);
        Long userId = getUserId();
        if(userId==Constant.SUPER_ADMIN || userId==Constant.ADMIN){
            if(itemPageForm.getDatasetId()==-1){
                map.remove("datasetId");
            }
        }else{
            if(itemPageForm.getDatasetId()==-1){
                Map<String, Object> map1 = new HashMap<>();
                map1.put("user_id",userId);
                List<MarkTeamUserEntity> teamList = markTeamUserDao.selectByMap(map1);
                List<Integer> teams = teamList.stream().map(team -> team.getTeamId()).collect(Collectors.toList());
                if(teams.size()==0){
                    return R.ok();
                }
                map.put("teams",teams);
                map.remove("datasetId");
            }
        }
        if(itemPageForm.getState()==null || itemPageForm.getState()==-1){
            map.put("min",ItemConstant.ItemType.MARK.getValue());
        }
        PageUtils page = markItemService.queryPage(map);
        R ok = R.ok();
        ok.put("page", page);
        return ok;
    }

    /**
     * 审批图片
     */
    @PostMapping("/approveItem")
    @ApiOperation("审批图片")
    @RequiresPermissions("mark:markitem:approve")
    public R approveItem(@RequestBody MarkItemEntity markItem){
        if(markItem.getItemId()==null){
            throw new RRException("请传入图片id");
        }
        if(markItem.getState()==null){
            throw new RRException("输入参数有误");
        }
        if(markItem.getDatasetId()==null){
            throw new RRException("请输入任务id");
        }
        if(markItem.getState()!=ItemConstant.ItemType.PASS.getValue()){
            throw new RRException("输入参数有误");
        }
        //查询之前的状态
        MarkItemEntity entity = markItemService.getById(markItem.getItemId());
        if(entity.getState()==ItemConstant.ItemType.PASS.getValue()){
            throw new RRException("该图片已经审批完成，无法重复审批");
        }
        if(entity.getState()<ItemConstant.ItemType.MARK.getValue()){
            throw new RRException("该图片还未提交，无法审批");
        }
        markItem.setState(markItem.getState());
        Long userId = getUserId();
        markItem.setApproveId(userId);
        if(markItem.getLocations()!=null && markItem.getLocations().size()>0){
            List<Location> locations = markItem.getLocations();
            String jsoStr = JSON.toJSONString(locations);
            markItem.setLocation(jsoStr);
        }
        markItemService.approve(markItem);
        return R.ok();
    }

    @GetMapping("/getState")
    @ApiOperation("获取状态")
    public R getState(){
        Map<Integer, String> map = ItemConstant.TYPELIST;
        map.remove(0);
        List list = new ArrayList();
        for(Map.Entry<Integer, String> entry : map.entrySet()){
            Map map1 = new HashMap();
            map1.put("key",entry.getKey());
            map1.put("value",entry.getValue());
            list.add(map1);
        }
        return R.ok().put("list",list);
    }


    @PostMapping("/saveItems")
    @ApiOperation("保存多张图片")
    public R saveItems(@Valid @RequestBody ItemForm itemForm){
        if(itemForm.getUrls().size()==0){
            return R.error(500,"请选择图片");
        }
        MarkDatasetEntity datasetEntity = markDatasetDao.selectById(itemForm.getDatasetId());
        if(datasetEntity.getState()>0){
            throw new RRException("该任务已经被分发了，不能新增图片");
        }
        try{
            markItemService.saveAll(itemForm);
        }catch (Exception e){
            throw new RRException("保存数据库失败，请重试");
        }
        return R.ok();
    }


    /**
     * 删除
     */
    @PostMapping("/delete")
    @ApiOperation("删除图片")
    @RequiresPermissions("mark:markdataset:delete")
    public R delete(@RequestBody ItemForm itemForm) {
        markItemService.deleteByIds(itemForm);
        return R.ok();
    }

    //统计
    @GetMapping("/count")
    public R count(){
        Long userId = getUserId();
        QueryWrapper<MarkItemEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId).eq("state", ItemConstant.ItemType.SEND.getValue());
        //未提交
        Integer noSubmit= markItemDao.selectCount(wrapper);
        wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId).eq("state", ItemConstant.ItemType.MARK.getValue());
        //待审核
        Integer approve = markItemDao.selectCount(wrapper);
        wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId).eq("state", ItemConstant.ItemType.PASS.getValue());
        //通过
        Integer pass = markItemDao.selectCount(wrapper);
        wrapper = new QueryWrapper<>();
        Map map = new HashMap();
        map.put("noSubmit",noSubmit); //待提交
        map.put("approve",approve);   //待审批
        map.put("pass",pass);   //通过
        return R.ok().put("map",map);
    }

    //统计
    @GetMapping("/countAdmin")
    public R countAdmin(){
        QueryWrapper<MarkItemEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("state", ItemConstant.ItemType.SEND.getValue());
        //未提交
        Integer noSubmit= markItemDao.selectCount(wrapper);
        wrapper = new QueryWrapper<>();
        wrapper.eq("state", ItemConstant.ItemType.MARK.getValue());
        //待审核
        Integer approve = markItemDao.selectCount(wrapper);
        wrapper = new QueryWrapper<>();
        wrapper.eq("state", ItemConstant.ItemType.PASS.getValue());
        //通过
        Integer pass = markItemDao.selectCount(wrapper);
        Map map = new HashMap();
        map.put("noSubmit",noSubmit); //待提交
        map.put("approve",approve);   //待审批
        map.put("pass",pass);   //通过
        return R.ok().put("map",map);
    }

    //统计
    @GetMapping("/countApprove")
    public R countApprove(){
        Long userId = getUserId();
        QueryWrapper<MarkTeamUserEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("team_id").eq("user_id", userId);
        List<MarkTeamUserEntity> list = markTeamUserService.list(queryWrapper);
        List<Integer> teams = list.stream().map(MarkTeamUserEntity::getTeamId).collect(Collectors.toList());

        QueryWrapper<MarkItemEntity> wrapper = new QueryWrapper<>();
        wrapper.in("team_id", teams).eq("state", ItemConstant.ItemType.MARK.getValue());
        //待审核
        Integer approve = markItemDao.selectCount(wrapper);
        wrapper = new QueryWrapper<>();
        wrapper.in("team_id", teams).eq("state", ItemConstant.ItemType.PASS.getValue());
        //通过
        Integer pass = markItemDao.selectCount(wrapper);
        Map map = new HashMap();
        map.put("approve",approve);   //待审批
        map.put("pass",pass);   //通过
        return R.ok().put("map",map);
    }

    //统计
    @GetMapping("/countByData")
    public R countByData(){
        Long userId = getUserId();
        Map<String,Integer> map = new LinkedHashMap<String,Integer>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar ca = Calendar.getInstance();//得到一个Calendar的实例
        ca.setTime(new Date()); //设置时间为当前时间
        ca.add(Calendar.DATE, -6);
        String format = sdf.format(ca.getTime());
        map.put(format,0);
        ca.add(Calendar.DATE, 1);
        String format1 = sdf.format(ca.getTime());
        map.put(format1,0);
        ca.add(Calendar.DATE, 1);
        String format2 = sdf.format(ca.getTime());
        map.put(format2,0);
        ca.add(Calendar.DATE, 1);
        String format3 = sdf.format(ca.getTime());
        map.put(format3,0);
        ca.add(Calendar.DATE, 1);
        String format4 = sdf.format(ca.getTime());
        map.put(format4,0);
        ca.add(Calendar.DATE, 1);
        String format5 = sdf.format(ca.getTime());
        map.put(format5,0);
        ca.add(Calendar.DATE, 1);
        String format6 = sdf.format(ca.getTime());
        map.put(format6,0);

        String day1 = format6+" 23:59:59";
        String day = format+" 00:00:00";

        Map<String,Integer> approveMap = new LinkedHashMap<String,Integer>();
        Iterator it = map.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String,Integer> entry = (Map.Entry) it.next();
            approveMap.put(entry.getKey(), map.get(entry.getKey()));
        }

        QueryWrapper<MarkTeamUserEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("team_id").eq("user_id", userId);
        List<MarkTeamUserEntity> list = markTeamUserService.list(queryWrapper);
        List<Integer> teams = list.stream().map(MarkTeamUserEntity::getTeamId).collect(Collectors.toList());

        QueryWrapper<MarkItemEntity> wrapper = new QueryWrapper<>();

        //用户角色
        Map role = new HashMap();
        role.put("user_id",userId);
        List<SysUserRoleEntity> roleList = sysUserRoleDao.selectByMap(role);
        List<Long> collect = roleList.stream().map(r -> r.getRoleId()).collect(Collectors.toList());
        if(getUserId()==1 || getUserId()==2){
            wrapper.select("update_time,state").gt("update_time",day).lt("update_time",day1)
                    .ge("state",2);
        }else if(collect.contains(1l)){
            wrapper.select("update_time,state").in("team_id", teams).gt("update_time",day).lt("update_time",day1)
                    .ge("state",2);
        }else if(collect.contains(2l)){
            wrapper.select("update_time,state").eq("user_id", userId).gt("update_time",day).lt("update_time",day1)
                    .ge("state",2);
        }else{
            return R.ok();
        }
        List<MarkItemEntity> entities = markItemDao.selectList(wrapper);
        for (MarkItemEntity entity : entities) {
            String time = sdf.format(entity.getUpdateTime());
            if(entity.getState()==3){
                for(Map.Entry<String, Integer> ent : map.entrySet()){
                    if(time.contains(ent.getKey())){
                        ent.setValue(ent.getValue()+1);
                        break;
                    }
                }
            }else if(entity.getState()==2) {
                for (Map.Entry<String, Integer> ent : approveMap.entrySet()) {
                    if (time.contains(ent.getKey())) {
                        ent.setValue(ent.getValue() + 1);
                        break;
                    }
                }
            }
        }
        List<Map> list1 = new ArrayList<>();
        list1.add(map);
        list1.add(approveMap);

        return R.ok().put("list",list1);
    }
}
